import time
from typing import Dict, Any

import bson
from pydantic import BaseModel, Field, PrivateAttr
from .value_objects import UUID


class Entity(BaseModel):
    _init_snapshot: Dict[str, Any] = PrivateAttr()

    class Config:
        use_enum_values = True

    def __init__(self, **data):
        super().__init__(**data)
        # TODO 嵌套引用类型需要deepcopy 暂不支持
        self._init_snapshot = {key: getattr(self, key) for key in self.__fields_set__}

    def diff(self):
        diff_dict = {}
        for name in self.__fields_set__:
            if name not in self._init_snapshot or self._init_snapshot.get(name) != getattr(self,
                                                                                           name):
                diff_dict[name] = getattr(self, name)
                continue
        return diff_dict


class AggregateRoot(Entity):
    pass


class PyObjectId(bson.ObjectId):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, value):
        try:
            return cls(value)
        except bson.errors.InvalidId:
            raise ValueError("Not a valid ObjectId")
